#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <assert.h>
#include <algorithm>
#include <functional>
using namespace std;
//template <class T>// 递归终止函数
//void ShowList(const T& t)
//{
//	cout << t << endl;
//}
//
//template <class T, class ...Args>// 展开函数
//void ShowList(T value, Args... args)
//{
//	cout << value << " ";
//	ShowList(args...);
//}

//template <class T>
//int PrintArg(T t)
//{
//	cout << t << " ";
//}
//
//template <class ...Args>//展开函数
//void ShowList(Args... args)
//{
//	int arr[] = { (PrintArg(args), 0)... };
//	cout << endl;
//}
//
//int main()
//{
//	ShowList(1);
//	ShowList(1, 'R');
//	ShowList(1, 'R', std::string("left"));
//	return 0;
//}
//template <class T>
//int PrintArg(T t)
//{
//	cout << t << " ";
//	return 0;
//}
//
//template <class ...Args>//展开函数
//void ShowList(Args... args)
//{
//	int arr[] = { PrintArg(args)... };
//	cout << endl;
//}
//
//int main()
//{
//	ShowList(1);
//	ShowList(1, 'R');
//	ShowList(1, 'R', std::string("left"));
//	return 0;
//}

//int main()
//{
//	list<int> mylist;
//	mylist.push_back(10);
//	mylist.push_back(20);
//	mylist.emplace_back(30);
//	mylist.emplace_back(40);
//	//mylist.emplace_back(50, 60); //不能这样用
//
//	for (const auto& e : mylist)
//	{
//		cout << e << endl;
//	}
//
//	return 0;
//}

//int main()
//{
//	list<pair<int, char>> mylist;
//
//	mylist.push_back({ 10, 'a' });
//	mylist.emplace_back(20, 'b');
//
//	mylist.push_back(make_pair(30, 'c'));
//	mylist.emplace_back(make_pair(40, 'd'));
//
//	mylist.emplace_back(50, 'e');
//
//	for (const auto& e : mylist)
//	{
//		cout << e.first << ":" << e.second << endl;
//	}
//	return 0;
//}

//namespace rtx
//{
//	class string
//	{
//	public:
//		string(const char* str = "")
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//			cout << "string(const char* str = "") -- 构造函数" << endl;
//		}
//
//		void swap(string& s)
//		{
//			::swap(_str, s._str);
//			::swap(_size, s._size);
//			::swap(_capacity, s._capacity);
//		}
//
//		string(const string& s) // 拷贝构造
//			:_str(nullptr)
//			, _size(0)
//			, _capacity(0)
//		{
//			cout << "string(const string& s) -- 拷贝构造(深拷贝)" << endl;
//			string tmp(s._str);
//			swap(tmp);
//		}
//
//		string(string&& s) // 移动构造
//			:_str(nullptr)
//			, _size(0)
//			, _capacity(0)
//		{
//			cout << "string(string&& s) -- 移动构造(资源转移)" << endl;
//			swap(s);
//		}
//
//		string& operator=(const string& s) // 拷贝赋值
//		{
//			cout << "string& operator=(string s) -- 拷贝赋值(深拷贝)" << endl;
//			string tmp(s);
//			swap(tmp);
//
//			return *this;
//		}
//
//		string& operator=(string&& s) // 移动赋值
//		{
//			cout << "string& operator=(string s) -- 移动赋值(资源移动)" << endl;
//			swap(s);
//
//			return *this;
//		}
//
//		~string()
//		{
//			delete[] _str;
//			_str = nullptr;
//		}
//
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//
//				_capacity = n;
//			}
//		}
//
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//
//			_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//
//	protected:
//		char* _str;
//		size_t _size;
//		size_t _capacity;
//	};
//}
//
//int main()
//{
//	std::list< std::pair<int, rtx::string> > mylist;
//	mylist.emplace_back(10, "sort");
//	mylist.emplace_back(make_pair(20, "sort"));
//	cout << "#########################################" << endl;
//	mylist.push_back(make_pair(30, "sort"));
//	mylist.push_back({ 40, "sort" });
//	return 0;
//}

//#include <algorithm>
//#include <functional>
//int main()
//{
//	int arr[] = { 4,1,8,5,3,7,0,9,2,6 };
//	// 默认按照小于比较，排出来结果是升序
//	std::sort(arr, arr + sizeof(arr) / sizeof(arr[0]));
//	// 如果需要降序，需要改变元素的比较规则
//	std::sort(arr, arr + sizeof(arr) / sizeof(arr[0]), greater<int>());
//	return 0;
//}
//
//struct Goods
//{
//	string _name; // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//struct ComparePriceLess
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 7 }, { "西瓜", 5.5,3 }, { "橘子", 7.7, 4 } };
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//}

//int main()
//{
//	// 交换变量的lambda
//	int x = 0, y = 7;
//	auto swap1 = [](int& x1, int& x2)->void{int tmp = x1; x1 = x2; x2 = tmp; };
//	swap1(x, y);
//	cout << x << "-------" << y << endl;
//
//	auto swap2 = [](int& x1, int& x2)
//	{
//		int tmp = x1;
//		x1 = x2;
//		x2 = tmp;
//	};
//	swap2(x, y);
//	cout << x << "-------" << y << endl;
//
//	auto swap3 = [x, y](int& x1, int& x2)
//	{
//		int tmp = x1;
//		x1 = x2;
//		x2 = tmp;
//	};
//	swap3(x, y);
//	cout << x << "-------" << y << endl;
//	swap3(x, y);
//	cout << x << "-------" << y << endl;
//	return 0;
//}
//struct Goods
//{
//	string _name; // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 7 }, { "西瓜", 5.5,3 }, { "橘子", 7.7, 4 } };
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) 
//		{return g1._price < g2._price; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) 
//		{return g1._price > g2._price; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) 
//		{return g1._evaluate < g2._evaluate; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) 
//		{return g1._evaluate > g2._evaluate; });
//	return 0;
//}

//int main()
//{
//	int a, b, c, d, e;
//	a = b = c = d = e = 1;
//
//	auto f1 = [=]() // 全部传值捕捉
//	{
//		cout << a << b << c << d << e << endl;
//	};
//	f1();
//
//	auto f2 = [=, &a]() // 混合捕捉
//	{
//		a++;
//		cout << a << b << c << d << e << endl;
//	};
//	f2();
//
//	return 0;
//}

//int main()
//{
//	int a = 3, b = 4;
//
//	// 省略参数列表和返回值类型，返回值类型由编译器推导为int
//	auto fun = [=] {return a + 3; };
//	cout << fun() << endl;
//
//	// 省略了返回值类型，无返回值类型
//	auto fun1 = [&](int c) {b = a + c; };
//	fun1(10);
//	cout << a << " " << b << endl;
//
//	// 各部分都很完善的lambda函数
//	auto fun2 = [=, &b](int c)->int {return b += a + c; };
//	cout << fun2(10) << endl;
//
//	// 复制捕捉x
//	int x = 10;
//	auto add_x = [x](int a) mutable { x *= 2; return a + x; };
//	cout << add_x(10) << endl;
//	return 0;
//}

//// 要求delete关键字实现，一个类，只能在堆上创建对象
//class HeapOnly
//{
//public:
//	HeapOnly()
//	{
//		_str = new char[10];
//	}
//
//	~HeapOnly() = delete;
//
//	//void Destroy() // 如果要销毁只能这样
//	//{
//	//	delete[] _str;
//
//	//	operator delete(this);
//	//}
//
//private:
//	char* _str;
//	//...
//};

//void (*PF)();
//int main()
//{
//	auto f1 = [] {cout << "hello world" << endl; };
//	auto f2 = [] {cout << "hello world" << endl; };
//	// 此处先不解释原因，等lambda表达式底层实现原理看完后，就清楚了
//    // f1 = f2;   // 编译失败--->提示找不到operator=()
//	// 允许使用一个lambda表达式拷贝构造一个新的副本
//	auto f3(f2);
//	f3();
//	// 可以将lambda表达式赋值给相同类型的函数指针，但基本不会用
//	PF = f2;
//	PF();
//	return 0;
//}

class Rate
{
public:
	Rate(double rate) : _rate(rate)
	{}
	double operator()(double money, int year)
	{
		return money * year * _rate;
	}
private:
	double _rate;
};

//int main()
//{
//	// 函数对象
//	double rate = 0.5;
//	Rate r1(rate);
//	cout << r1(518, 3) << endl;
//
//	// lambda
//	auto r2 = [=](double money, int year)->double {return money * year * rate;};
//	cout << r2(518, 3) << endl;
//
//	return 0;
//}

//template<class F, class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//	return f(x);
//}
//double f(double i)
//{
//	return i / 2;
//}
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//int main()
//{
//	// 函数名
//	cout << useF(f, 11.11) << endl;
//	// 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//	// lambda表达式对象
//	cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//	return 0;
//} 

//int f(int a, int b)
//{
//	return a + b;
//}
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//int main()
//{
//	std::function<int(int, int)> func1 = f; // 函数名(函数指针)
//	cout << func1(1, 2) << endl;
//
//	std::function<int(int, int)> func2 = Functor(); // 函数对象
//	cout << func2(1, 2) << endl;
//
//	std::function<int(int, int)> func3 = [](const int a, const int b)
//	{return a + b; }; // lambda表达式
//	cout << func3(1, 2) << endl;
//
//	std::function<int(int, int)> func4 = &Plus::plusi; // 类的静态成员函数
//	cout << func4(1, 2) << endl;
//
//	std::function<double(Plus, double, double)> func5 = &Plus::plusd;
//	cout << func5(Plus(), 1.1, 2.2) << endl; // 类的成员函数需要用对象调用
//	return 0;
//}

template<class F, class T>

T useF(F f, T x)
{
	static int count = 0;
	cout << "count:" << ++count << endl;
	cout << "count:" << &count << endl;
	return f(x);
}

double f(double i)
{
	return i / 2;
}

struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};

int main()
{
	// 函数名
	function<double(double)> f1 = f;
	cout << useF(f1, 11.11) << endl;
	// 函数对象
	function<double(double)> f2 = Functor();
	cout << useF(f2, 11.11) << endl;
	// lambda表达式对象
	function<double(double)> f3 = [](double d)->double { return d / 4; };
	cout << useF(f3, 11.11) << endl;
	return 0;
}

//int Sub(int a, int b)
//{
//	return a - b;
//}
//using namespace placeholders; // _1, _2 要加命名空间
// 
//int main()
//{
//	int x = 2, y = 9;
//	cout << Sub(x, y) << endl;
//	//_1 _2.... 定义在placeholders命名空间中，代表绑定函数对象的形参，
//	//_1，_2...分别代表第一个形参、第二个形参...
//
//	//function<int(int, int)> bindFunc1 = bind(Sub, _1, _2); // 没换顺序
//	//function<int(int, int)> bindFunc2 = bind(Sub, _2, _1); // 换顺序了
//	auto bindFunc1 = bind(Sub, _1, _2); // 没换顺序
//	auto bindFunc2 = bind(Sub, _2, _1); // 换顺序了
//
//	cout << bindFunc1(x, y) << endl;
//	cout << bindFunc2(x, y) << endl;
//
//	return 0;
//}

//class A
//{
//public:
//	A() {}
//};
//
//void foo()
//{
//	throw new A;
//}
//
//int main()
//{
//	try 
//	{ 
//		foo();
//	}
//	catch (A ｘ)
//	{
//		cout << "throw A!";
//	}
//	return 0;
//}

//int main()
//{
//	// 两个数相加的lambda
//	auto add1 = [](int a, int b)->int {return a + b;};
//	auto add2 = [](int a, int b) {return a + b;};
//
//	cout << add1(1, 6) << endl;
//	cout << add2(1, 6) << endl;
//	return 0;
//}